A multi-core computing system comprises multiple processing units or ‘cores’; for example, a dual-core CPU comprises two processor cores, a quad-core CPU comprises four cores, etc., wherein the cores may typically be provided on a single chip (a single integrated circuit). A multi-core system allows true parallel processing of multiple processes or tasks such that, e.g., each process or task is executed on a dedicated core. The cores may share common resources, for example a cache or other storage, and/or the interconnections to other portions of the system. The usage of the shared resources has to be properly controlled, i.e. some synchronization of the multiple cores is required in particular to ensure a sequential access to the resources.
Typically a low-level synchronization mechanism is provided by a microcontroller of the multi-core system in the form of a set of instructions; for example, atomic test_and_set instruction(s) may be used to implement a spinlock mechanism. This low-level mechanism may then serve as the basis for service functions (e.g., a semaphore functionality) provided by an operating system.
A spinlock mechanism realizes a mutually exclusive operation of multiple cores with regard to a shared resource. A simple spinlock mechanism may work as follows:                multiple cores request the lock;        the lock is allocated to exactly one of the cores; this core may start processing by using the unlocked resource;        the other cores continue to request the lock, i.e. they repeatedly and continuously check whether the lock is available (“spinning”);        the operating core returns the lock after end of operation;        the lock is allocated to the core which happens to perform the first spinning attempt after the lock has been returned; this core may start processing, etc.        
Thus, an essential aspect of the spinlock mechanism is that the lock, if available, is allocated to the first core requesting it. This spinlock mechanism provides for a simple and generally efficient synchronization below the level of operating system rescheduling and is therefore widely employed, for example in personal computers or general purpose computers.
However, the simple spinlock mechanism does not allow to observe timing constraints. Specifically, it is not possible to calculate the maximum time or a time boundary it may take to fulfil a task. The simple spinlock mechanism allows a “starvation” of cores; i.e. it may happen that a core never receives the lock, because other cores are always faster. Thus, the spinlock mechanism is not deterministic. Moreover, a fair scheduling should also take into account the priorities of the tasks to be executed on the cores. The simple spinlock mechanism allows “priority inversion”, i.e. a low priority task executed on one core may block a high priority task on another core which has to wait for the lock.
The above drawbacks make the simple spinlock inappropriate for time-critical environments and in particular for real-time environments, i.e. configurations in which one or more real-time applications are executed on the multi-core system. A typical real-time environment is an automotive environment in which, e.g., safety-critical applications have to be performed. The behaviour of a real-time system (a multi-core system configured for a real-time environment) must be deterministic and fair. In order to make a spinlock-based scheduling applicable for real-time environments, the simple spinlock thus has to be modified.
One solution could be to provide an additional mechanism for, killing a task executed on a core once a time limit is exceeded. However, this mechanism requires additional control overhead, for example an additional mechanism to release the lock, and is still neither deterministic nor fair.
According to another solution, the scheduler may assign a ticket to each spinning core. Each ticket comprises a unique number which may be seen as a ‘waiting number’ such that the spinning cores are ordered by means of their ticket numbers into a strictly sequential sequence. The lock is then allocated to one core after another as indicated by the tickets. While at first glance this mechanism seems to guarantee that each of the spinning cores will receive the lock, there are still problems. Consider, for example, the case that a waiting core is no longer interested in getting the lock, for example because a time limit for the task to be performed has been exceeded, i.e. the waiting time has been too long and another processing path will be followed instead. When arriving at the ticket of this core, the proceeding controlled by the ticket sequence will hang-up, as the core will never return the lock. Thus, this ticket-based mechanism is not deterministic.
More sophisticated, queue-based techniques may be used, in which the spinning cores are sorted into a queue by defining preceding and succeeding relations between the cores. With regard to the queue then additional mechanisms may be defined, for example, a time-out mechanism which allows that a core may leave the queue due to an exceeded time limit or a re-scheduling from the operating system. However, such queue-based spinlocks are quite complicated. In particular for multi-core systems comprising only few cores the overhead introduced by queue-based spinlocks may be large compared to a simple spinlock. And the overhead will get even larger when additional mechanisms have to be introduced in order to consider the priorities of the tasks running on the cores.